import 'dart:async';
// import 'dart:html';
import 'dart:io';
import 'dart:math';

import 'package:blocks_blkk/components/communicator.dart';
import 'package:blocks_blkk/components/function_button.dart';
import 'package:blocks_blkk/components/steer.dart';
import 'package:blocks_blkk/data/command_data.dart';
// import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
// import 'package:flutter/widgets.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:logger/logger.dart';
import 'package:permission_handler/permission_handler.dart';

class AppHomePageState extends State<StatefulWidget>
    with WidgetsBindingObserver {
  bool startSearching = false;
  bool connected = false;
  int errTimes = 0;

  StreamSubscription? _connectedStateSubscription;
  StreamSubscription? _scanSubscription;
  StreamSubscription? _apaterStateSub;

  var logger = Logger();
  List<BluetoothDevice> avaliableDevice = [];
  BluetoothService? findService;
  BluetoothCharacteristic? findCharactric;
  Communicator? communicator;
  CommandData commandData = CommandData();

  Color get _buttonColor => connected ? Colors.blue : Colors.grey;

  @override
  void dispose() {
    super.dispose();
    _connectedStateSubscription?.cancel();
    _scanSubscription?.cancel();
    _apaterStateSub?.cancel();
    //3. 页面销毁时，移出监听者
    WidgetsBinding.instance.removeObserver(this);
  }

  // 手机自身蓝牙开关状态监听处理
  void adapterStateEvent(BluetoothAdapterState adapterState) {
    if (adapterState == BluetoothAdapterState.on) {
      //开始扫描
      // FlutterBluePlus.startScan();
      // if (startSearching) {
      logger.d('蓝牙开关状态打开');
      // if (FlutterBluePlus.isScanningNow) {
      //   startSearching = false;
      //   FlutterBluePlus.stopScan();
      // }
      // avaliableDevice.clear();
      // Future.delayed(const Duration(milliseconds: 2), () {
      //   FlutterBluePlus.startScan(
      //       withServices: [Guid('0000fff0-0000-1000-8000-00805f9b34fb')],
      //       timeout: const Duration(seconds: 15),
      //       androidUsesFineLocation: false);
      // });
      // }
    } else {
      if (FlutterBluePlus.isScanningNow == false) {
        FlutterBluePlus.stopScan();
      }
      // if (startSearching) {
      //   showMessage(context, '请检查手机蓝牙是否已经打开', Colors.red);
      // }
      setState(() {
        // bluetooth_index = 0;
      });
    }
    // startSearching = false;
  }

  // 开始扫描按钮事件触发
  void startScanBtn() {
    avaliableDevice.clear();
    startSearching = true;
    // animationController.forward(from: 0);
    _apaterStateSub?.cancel();
    _scanSubscription?.cancel();
    _apaterStateSub = FlutterBluePlus.adapterState.listen(adapterStateEvent);
    _scanSubscription = FlutterBluePlus.scanResults.listen(scanResultEvent);

    if (FlutterBluePlus.isScanningNow) {
      startSearching = false;
      FlutterBluePlus.stopScan();
    }
    FlutterBluePlus.startScan(
        // withServices: [Guid('0000fff0-0000-1000-8000-00805f9b34fb')],
        timeout: const Duration(seconds: 15),
        androidUsesFineLocation: false);
  }

  // 收到蓝牙监听事件
  void scanResultEvent(List<ScanResult> list) {
    for (var element in list) {
      String localName = element.device.platformName;
      DeviceIdentifier identifier = element.device.remoteId;
      if (!findExistDevice(element.device)) {
        avaliableDevice.add(element.device);
        if (localName.startsWith('HMTECH')) {
          logger.d('搜索到蓝牙设备, $localName $identifier ${element.device}');
          connectDevice(element.device);
        }
        // animationController.stop(canceled: false); //stopAnimation();
      }
    }

    // logger.d('可用蓝牙设备数量, ${avaliableDevice.length}');

    // if (avaliableDevice.isNotEmpty) {
    //   startSearching = false;
    //   FlutterBluePlus.stopScan();
    // }
  }

  bool findExistDevice(BluetoothDevice device) {
    BluetoothDevice? d = avaliableDevice
        .where((element) => element.remoteId == device.remoteId)
        .firstOrNull;
    return d != null;
  }

  void initPermission() {
    if (Platform.isAndroid) {
      WidgetsFlutterBinding.ensureInitialized();
      [
        Permission.location,
        Permission.storage,
        Permission.bluetooth,
        Permission.bluetoothConnect,
        Permission.bluetoothScan
      ].request();
    }
  }

  //蓝牙按钮
  Widget bluetootnBtn(
      {BoxShape shape = BoxShape.circle,
      Color background = Colors.transparent,
      required String image}) {
    double left = 10, top = 10, width = 50, height = 50;
    if (Platform.isIOS) {
      double screenHeight = MediaQuery.of(context).size.height;
      double screenWidth = MediaQuery.of(context).size.width;
      double w = max<double>(screenHeight, screenWidth);
      if (w > 1000) {
        left = 80;
        top = 10;
      }
    }

    return Positioned(
      left: ScreenUtil().setHeight(left),
      top: ScreenUtil().setHeight(top),
      width: ScreenUtil().setHeight(width),
      height: ScreenUtil().setHeight(height),
      child: FunctionBtn(
        image: image,
        onTap: () {
          startScanBtn();
        },
        shape: shape,
        shadowColor: Colors.transparent,
        backgroundColor: background,
      ),
    );
  }

  // 连接蓝牙设备
  connectDevice(BluetoothDevice device) {
    // 已连接时直接退出
    if (connected) {
      return;
    }

    FlutterBluePlus.stopScan();
    errTimes = 0;
    reconnect(device);

    // };
  }

  void allConnectStateListener() {
    FlutterBluePlus.events.onConnectionStateChanged.listen((event) {
      logger.d(
          'allConnectStateListener ${event.device} ${event.connectionState}');
    });
  }

  void reconnect(BluetoothDevice device) {
    logger.d('connect device ${device.platformName}');
    var connectedStateSubscription =
        device.connectionState.listen((BluetoothConnectionState state) {
      logger.d(' device ${device.remoteId} 连接状态 state = $state');
      if (state == BluetoothConnectionState.connected) {
        logger.d('链接成功 device == $device');

        Future.delayed(Duration(milliseconds: 200), () {
          findDeviceServices(device);
        });
      } else if (state == BluetoothConnectionState.disconnected) {
        setState(() {
          connected = false;
        });
      }
    });
    device
        .connect(timeout: const Duration(seconds: 10))
        .onError((error, stackTrace) {
      logger.d('连接设备失败  ${device.advName}', stackTrace: stackTrace);
      errTimes++;

      // Future.delayed(const Duration(milliseconds: 50), () {
      //   if (errTimes++ < 5) {
      //     reconnect(device);
      //   }
      // });
    });
    device.cancelWhenDisconnected(connectedStateSubscription,
        delayed: true, next: true);
  }

  void findDeviceServices(BluetoothDevice device) async {
    List<BluetoothService> services = await device.discoverServices();
    // services.forEach((service) {
    //   logger.d('service: ${service.uuid}');
    // });
    findService = services
        .where((element) =>
            element.uuid.toString() == '49535343-fe7d-4ae5-8fa9-9fafd205e455')
        .firstOrNull;
    if (findService != null) {
      setState(() {
        connected = true;
      });
    }
    findService?.characteristics.forEach((characteristic) {
      logger.d('characteristic: ${characteristic.uuid}');
      if (characteristic.uuid.toString() == 'ae3b') {
        communicator = Communicator(characteristic);
      }
    });
  }

  @override
  void initState() {
    initPermission();
    allConnectStateListener();
    // startScanBtn();

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        margin: const EdgeInsets.all(20),
        // color: Colors.grey,
        child: Stack(children: [
          bluetootnBtn(
              background: _buttonColor, image: 'assets/bluetooth_off.png'),
          Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                SizedBox(
                    // color: Colors.red,
                    width: ScreenUtil().setHeight(1000),
                    height: ScreenUtil().setHeight(250),
                    child: Stack(
                      children: [_steer()],
                    )),
              ],
            ),
          ),
        ]),
      ),
    );
  }

  final double _steerPosition = ScreenUtil().setHeight(10);
  final double _steerElse = ScreenUtil().setHeight(10);

  Widget _steer() {
    return Positioned(
      right: ScreenUtil().setHeight(5.0),
      left: ScreenUtil().setHeight(5.0),
      top: ScreenUtil().setHeight(5.0),
      bottom: ScreenUtil().setHeight(5.0),
      child: SizedBox(
        width: ScreenUtil().setHeight(280.0),
        height: ScreenUtil().setHeight(280.0),
        // color: Colors.green,
        child: Row(
          children: [
            // Text('nnnnn'),
            Expanded(child: Container()),
            _leftSteer(
                'seires_m_steer_left.png', 'seires_m_steer_thumb_left.png'),
            Expanded(flex: 2, child: Container()),
            _rightSteer(
                'seires_m_steer_right.png', 'seires_m_steer_thumb_right.png'),
            Expanded(child: Container()),
          ],
        ),
      ),
    );
  }

  Widget _leftSteer(final backgroundImg, final controlImg) {
    return Steer(
      left: _steerPosition,
      right: _steerElse,
      bottom: ScreenUtil().setHeight(5),
      width: ScreenUtil().setHeight(250.0),
      height: ScreenUtil().setHeight(250.0),
      changeValue: setVertical,
      direction: SteerMoveEnum.Vertical,
      backgroundImg: 'assets/$backgroundImg',
      controlImg: 'assets/$controlImg',
      lessImage: '',
      greatImage: '',
      recoverFunction: () {
        return true;
      },
    );
  }

  Widget _rightSteer(final backgroundImg, final controlImg) {
    return Steer(
      left: _steerElse,
      right: _steerPosition,
      bottom: ScreenUtil().setHeight(5),
      width: ScreenUtil().setHeight(250.0),
      height: ScreenUtil().setHeight(250.0),
      radio: 0.35,
      changeValue: setHorizontal,
      direction: SteerMoveEnum.Horizontal,
      backgroundImg: 'assets/$backgroundImg',
      controlImg: 'assets/$controlImg',
      lessImage: '',
      greatImage: '',
      recoverFunction: () {
        return true;
      },
    );
  }

  // List<int> list = [0xAB, 0xCD, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
  // void fillSUm() {
  //   list[9] =
  //       0x01 + list[3] + list[4] + list[5] + list[6] + list[7] + list[8] + 01;
  // }

  // void setVertical({double? x, double? y}) {
  //   // print('setVertical ${x!.toStringAsFixed(2)} ${y!.toStringAsFixed(2)}');
  //   int val = (y! * 128.0).toInt() & 0xFF;
  //   list[3] = val;
  //   fillSUm();
  //   // print(list);
  //   communicator?.sendData(list, force: val == 0);
  // }

  // void setHorizontal({double? x, double? y}) {
  //   int val = (x! * 128.0).toInt() & 0xFF;
  //   list[4] = val;
  //   fillSUm();
  //   // print(list);
  //   communicator?.sendData(list, force: val == 0);
  // }

  bool zeroForce = false;
  void setVertical({double? x, double? y}) {
    // print('setVertical ${x!.toStringAsFixed(2)} ${y!.toStringAsFixed(2)}');
    if (y!.abs() < 0.1) {
      communicator?.sendData(commandData.setAction(vertical: 0),
          force: zeroForce);
      zeroForce = false;
    } else {
      zeroForce = true;
      communicator?.sendData(commandData.setAction(vertical: y));
    }
  }

  void setHorizontal({double? x, double? y}) {
    // print('setHorizontal ${x!.toStringAsFixed(2)} ${y!.toStringAsFixed(2)}');
    if (x!.abs() < 0.1) {
      communicator?.sendData(commandData.setAction(horizontal: 0),
          force: zeroForce);
      zeroForce = false;
    } else {
      zeroForce = true;
      communicator?.sendData(commandData.setAction(horizontal: x));
    }
  }
}
